#include <libuserangel.h>

#include <err.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <sys/socket.h>
#include <sys/un.h>


void sender(int);
void receiver(int);


int main(int argc, char *argv[])
{
	int sockets[2];

	if(socketpair(AF_UNIX, SOCK_STREAM, 0, sockets))
		err(-1, "Error in socketpair()");


	int pid = fork();
	if(pid < 0) err(-1, "Error in fork()");
	else if(pid > 0)
	{
		close(sockets[1]);
		sender(sockets[0]);
	}
	else
	{
		close(sockets[0]);
		receiver(sockets[1]);
	}

	return 0;
}


void sender(int sock)
{
	/* send several times */
	for(int i = 0; i < 10; i++)
	{
		int fd = open("/etc/passwd", O_RDONLY);
		if(fd < 0) err(-1, "Error opening passwd file");

		char buf[80];
		bzero(buf, 80);
		if(read(fd, buf, 40) < 0) err(-1, "Error reading from FD");

		struct ua_datum *d = ua_marshall_string("fubar", 5);
		if(ua_send(sock, d, &fd, 1) < 0) err(-1, "Error in ua_send()");

		free(d);
		close(fd);
	}
}


void receiver(int sock)
{
	for(int i = 0; i < 10; i++)
	{
		size_t len = 2;
		int fds[len];
		for(int j = 0; j < len; j++) fds[j] = -1;

		struct ua_datum *d = ua_recv(sock, fds, &len);
		if(!d) err(-1, "Error in ua_recv()");
		if(len != 1) err(-1, "Should've received 1 FD, not %zu", len);

		if((fds[0] < 3) || (fds[0] >= FD_SETSIZE))
			err(-1, "Received invalid FD: %i", fds[0]);

		size_t namelen = 256;
		char buffer[namelen];
		if(ua_unmarshall_string(d, buffer, &namelen) < 0)
			err(-1, "Error unmarshalling filename");

		char buf[80];
		bzero(buf, sizeof(buf));

		if(read(fds[0], buf, 40) < 0) err(-1, "Error in read()");

		close(fds[0]);
		free(d);
	}

	printf("OK\n");
}

